package com.lh.controller;

import com.lh.model.User;
import com.lh.service.FileService;
import com.lh.service.UserService;
import com.lh.util.MyException;
import com.lh.util.MyLog;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

/**
 * Swagger API 文档Controller测试类
 *
 * @Author LuoHang
 * @Date 2022-05-08 19:54
 **/
@Api(tags = "测试User的Api")
@Controller
public class UserController {
    @Resource
    private UserService userService;

    @Autowired
    @Qualifier("fileServiceImpl")
    private FileService fileService;

    @ApiOperation(value = "获取用户信息",notes = "通过id获取用户的信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path",name = "uid",value = "用户id",dataType = "Integer")
    })
    @ApiResponses({
            @ApiResponse(code = 200,message = "请求成功"),
            @ApiResponse(code = 400,message = "缺少请求参数"),
            @ApiResponse(code = 401,message = "请求路径没有相应权限"),
            @ApiResponse(code = 403,message = "请求路径被隐藏不能访问"),
            @ApiResponse(code = 404,message = "缺少请求参数"),
            @ApiResponse(code = 405,message = "请求方法不支持")
    })
    @GetMapping(value = "/user/{uid}")
    public @ResponseBody User getUserByIdRestFul(@PathVariable(value = "uid") Integer id){
        User user = userService.getUserById(id);
        user.setId(id);
        return user;
    }

    /**
     * 注解：@RequestParam(value = "uid",required = false) Integer id
     *       value = "uid"：前端传入的形参名
     *       required = false：前端是否必须传入此参数，默认为true必须传入；false非必须
     * @param id id
     * @return User
     */
    @RequestMapping(value = "user/getUserById")
    public @ResponseBody User getUserById(@RequestParam(value = "uid",required = false) Integer id, HttpServletRequest request){
        MyLog.info(UserController.class,"测试拦截器预处理方法preHandle()中添加数据" + request.getAttribute("test").toString());
        return userService.getUserById(id);
    }

    /**
     * 用户添加测试
     * @param user 用户
     * @param model 数据模型
     * @return 视图
     */
    @PostMapping(value = "/user/addUser")
    public String addUser(User user, Model model){
        if (userService.addUser(user)){
            model.addAttribute("addSucMsg","添加用户成功");
            model.addAttribute("user",user);
        }else {
            model.addAttribute("addMsg","添加用户失败");
        }
        return "index";
    }

    /**
     * 用户添加数据时发生异常事务回滚测试
     * @param user 用户
     * @param model 数据模型
     * @return 视图
     * @throws MyException 自定义异常
     */
    @PostMapping(value = "/user/addUserException")
    public String addUserException(User user, Model model) throws MyException {
        if (!userService.addUserException(user)){
            model.addAttribute("addExcMsg","添加用户成功");
            model.addAttribute("user",user);
        }
        return "index";
    }

    /**
     * 嵌套事务请求
     * @param user 用户
     * @param multipartFile 文件
     * @return 信息
     * @throws MyException 异常
     */
    @PostMapping(value="/user/addUserAndImg")
    public @ResponseBody String addUserAndImg(User user, @RequestPart("file")MultipartFile multipartFile) throws MyException {
        //上传用户图片
        String filename = System.currentTimeMillis() + multipartFile.getOriginalFilename();
        String path = "D:/java code/static/images/" + filename;
        File file = new File(path);
        if (!file.exists()){
            MyLog.info(FileController.class,file.mkdirs() ? "创建成功：" + path : "创建失败");
        }
        //addUserAngImg()是嵌套事务逻辑
        user = userService.addUserAngImg(user,new com.lh.model.File(null,path,filename,user.getId()));
        try {
            //如果userService.addUserAngImg()插入数据异常抛MyException，是不会进行IO操作的
            multipartFile.transferTo(file);
        } catch (IOException e) {
            //执行到最后说明用户与文件对象都已经写入到数据库了，但是文件IO输出的时候异常导致失败，需要删除原始写入的数据
            userService.deleteById(user.getId());
            //这里其实是要传file id
            fileService.deleteById(user.getId());
            //抛出异常返回前端，图片上传失败，交给全局异常处理类处理
            throw new MyException(e.getMessage());
        }
        return "添加成功！！！";
    }
}
